﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TbShop.Web.Helpers;
using TbShop.Entity;
using HeinQi.Framework.Common.Caching;
using Autofac;
using HeinQi.Framework.LayerBases;
using System.Reflection;
using TbShop.Web.Areas.Admin.Models;
using TbShop.Business.Components;
using PagedList;
using Newtonsoft.Json;
using TbShop.Web.Infrastructure;
using TbShop.Web.Infrastructure.Identity;

namespace TbShop.Web.Areas.Admin.Controllers
{
    public class BaseController : Controller
    {
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var attrs = filterContext.ActionDescriptor.GetCustomAttributes(typeof(AllowAnonymousAttribute), false);
            if (!attrs.Any(p => p.GetType() == typeof(AllowAnonymousAttribute)) && string.IsNullOrEmpty(AdminId))
            {
                filterContext.HttpContext.Response.Redirect(Url.Action("Login", "Account") + "?returnUrl=" + GetUrl(filterContext.HttpContext.Request.Url.PathAndQuery), true);
            }
            else
            {
                base.OnActionExecuting(filterContext);
            }
        }

        protected string GetUrl(string path)
        {
            return HttpUtility.UrlEncode(path);
        }

        protected string AdminId
        {
            get
            {
                return SessionHelper.Get<string>(StaticWords.SessionUserIdKey);
            }
        }

        protected ApplicationUser CurrentAdmin
        {
            get
            {
                return AdminHelper.GetAdminById(this.AdminId);
            }
        }

        protected string OperationUser
        {
            get
            {
                return SessionHelper.Get<string>(StaticWords.SessionUserNameKey);
            }
        }

        protected string RoleId
        {
            get
            {
                return SessionHelper.Get<string>(StaticWords.SessionRoleIdKey);
            }
        }

        /// <summary>
        /// 发送前台弹框消息，页面刷新或跳转后显示
        /// </summary>
        /// <param name="message">消息内容</param>
        /// <param name="type">消息类型，支持：alert - success - error - warning - information - confirmation</param>
        public void SendMessage(string message = "", string type = "success")
        {
            Session["alert_message"] = message;
            Session["alert_message_type"] = type;
        }
    }


    public static class DataEntityBaseExtension
    {
        public static void FillEntity(this DataEntityBase item, string optionUser)
        {
            if (item.Id <= 0)
            {
                item.VersionNumber = 1;
                item.CreatedDate = DateTime.Now;
                item.CreatedBy = optionUser;
            }
            else
            {
                item.VersionNumber++;
            }
            item.UpdatedDate = DateTime.Now;
            item.UpdatedBy = optionUser;
        }
    }


    /// <summary>
    /// 单表管理通用Controller
    /// </summary>
    /// <typeparam name="TEntity">数据实体类型</typeparam>
    /// <typeparam name="TViewModel">页面实体类型</typeparam>
    public class BaseCacheManageController<TEntity, TViewModel> : BaseController
        where TEntity : DataEntityBase
        where TViewModel : BaseViewModel
    {
        /// <summary>
        /// 模块名称，用于显示页面
        /// </summary>
        private string ModuleName { set; get; }

        /// <summary>
        /// 模块ID，用于选中菜单
        /// </summary>
        private string ModuleId { set; get; }

        /// <summary>
        /// Controller名称，用于跳转页面
        /// </summary>
        private string ControllerName { set; get; }

        /// <summary>
        /// 是否从缓存中获取数据
        /// </summary>
        private bool FromCache { set; get; }

        /// <summary>
        /// 是否物理删除
        /// </summary>
        private bool PhysicalDelete { set; get; }

        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="moduleName">模块名称，用于显示页面</param>
        /// <param name="moduleId">模块ID，用于选中菜单</param>
        /// <param name="controllerName">Controller名称，用于跳转页面</param>
        /// <param name="fromCache">是否从缓存中获取数据</param>
        /// <param name="physicalDelete">是否是物理删除</param>
        public BaseCacheManageController(string moduleName, string moduleId, string controllerName, bool fromCache = false, bool physicalDelete = false)
        {
            this.ModuleName = moduleName;
            this.ModuleId = moduleId;
            this.ControllerName = controllerName;
            this.FromCache = fromCache;
            this.PhysicalDelete = physicalDelete;
        }

        protected ServiceComponents<TEntity> bc = new ServiceComponents<TEntity>();

        /// <summary>
        /// 列表管理页面
        /// </summary>
        /// <returns></returns>
        public virtual ActionResult Index()
        {
            ViewBag.ModuleName = this.ModuleName;
            ViewBag.ModuleId = this.ModuleId;
            return View();
        }

        /// <summary>
        /// 获取列表页面数据
        /// </summary>
        /// <param name="pageSize"></param>
        /// <param name="pageNumber"></param>
        /// <returns></returns>
        public virtual string GetDataList(int pageSize = 0, int pageNumber = 0)
        {
            IPagedList<TEntity> data = null;
            if (FromCache)
                data = CacheHelper<TEntity>.GetAll().ToPagedList(pageNumber, pageSize);
            else
                data = bc.GetAll().ToPagedList(pageNumber, pageSize);
            var meta = data.GetMetaData();
            var counts = meta.TotalItemCount;
            return JsonConvert.SerializeObject(new { total = counts, rows = DataMapperHelper.MapList<TViewModel>(data) });
        }

        /// <summary>
        /// 修改/添加页面
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public virtual ActionResult Edit(int id = 0)
        {
            ViewBag.ControllerName = this.ControllerName;
            ViewBag.ModuleName = this.ModuleName;
            ViewBag.ModuleId = this.ModuleId;
            ViewBag.CurrentAdminId = AdminId;
            if (id > 0)
            {
                TEntity data = null;
                if (FromCache)
                    data = CacheHelper<TEntity>.GetById(id);
                else
                    data = bc.Get(id);
                return View(DataMapperHelper.Map<TViewModel>(data));
            }
            return View(DataMapperHelper.Map<TViewModel>(new DataEntityBase { }));
        }

        /// <summary>
        /// 保存数据
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        [HttpPost]
        [ValidateAntiForgeryToken]
        public virtual ActionResult Edit(TViewModel model)
        {
            var newId = SaveData(model);
            if (newId > 0)
            {
                if (FromCache)
                    CacheHelper<TEntity>.ClearDates();
                SendMessage("保存成功", Constants.MessageType.Success);
                return RedirectToAction("Index");
            }
            else
            {
                SendMessage("保存失败", Constants.MessageType.Warning);
            }
            return RedirectToAction("Edit", new { id = newId });
        }

        /// <summary>
        /// 保存到数据库
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public virtual int SaveData(TViewModel model)
        {
            var data = DataMapperHelper.Map<TEntity>(model);
            data.FillEntity(User.Identity.Name);
            var saveResult = bc.Save(data);
            if (saveResult != null)
            {
                OperationLogHelper.SaveOperationLog(AdminId, (model.Id > 0 ? "修改" : "添加"), ModuleName, "", saveResult.Id.ToString());
                if (FromCache)
                    CacheHelper<TEntity>.ClearDates();
                return saveResult.Id;
            }
            return 0;
        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="id"></param>
        /// <param name="versionNumber"></param>
        /// <returns></returns>
        [HttpPost]
        [ValidateAntiForgeryToken]
        public virtual string DeleteData(int id, int versionNumber)
        {
            try
            {
                var result = false;
                if (this.PhysicalDelete)
                    result = bc.Delete(id, versionNumber);
                else
                    result = bc.Remove(id, versionNumber) != null;
                if (result)
                {
                    OperationLogHelper.SaveOperationLog(AdminId, "删除", ModuleName, "", id.ToString());
                    if (FromCache)
                        CacheHelper<TEntity>.ClearDates();
                    SendMessage("删除成功", Constants.MessageType.Success);
                    return "1";
                }
                else
                {
                    return "0";
                }
            }
            catch (CustomerException.VersioNumberException e)
            {
                return "-1";
            }
        }
    }
}